<!DOCTYPE html>
<html>
<head>
    <title>首页</title>
    {% include 'system/common/header.html' %}
    <link rel="stylesheet" href="{{ url_for('static', filename='system/admin/css/other/monitor.css') }}"/>
</head>
<body class="pear-container">
<div class="layui-row layui-col-space10">
    <div class="layui-col-md8">
        <div class="layui-row layui-col-space10">
            <div class="layui-col-md6" id="host-info-card">
                <div class="layui-card">
                    <div class="layui-card-header">
                        主机监控
                    </div>
                    <div class="layui-card-body">
                        <div class="layui-row layui-col-space10">
                            <div class="layui-col-md6 layui-col-sm6 layui-col-xs6">
                                <div class="pear-card2">
                                    <div class="title">核心数</div>
                                    <div class="count pear-text" id="cpu_count">-</div>
                                </div>
                            </div>
                            <div class="layui-col-md6 layui-col-sm6 layui-col-xs6">
                                <div class="pear-card2">
                                    <div class="title">空闲率</div>
                                    <div class="count pear-text" id="cpu_idle_percent">-%</div>
                                </div>
                            </div>
                            <div class="layui-col-md6 layui-col-sm6 layui-col-xs6">
                                <div class="pear-card2">
                                    <div class="title">等待率</div>
                                    <div class="count pear-text" id="cpu_wait_percent">-%</div>
                                </div>
                            </div>
                            <div class="layui-col-md6 layui-col-sm6 layui-col-xs6">
                                <div class="pear-card2">
                                    <div class="title">使用率</div>
                                    <div class="count pear-text" id="cpus_percent">-%</div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="layui-col-md6">
                <div class="layui-card">
                    <div class="layui-card-header">
                        内存监控
                    </div>
                    <div class="layui-card-body">
                        <div class="layui-row layui-col-space10">
                            <div class="layui-col-md6 layui-col-sm6 layui-col-xs6">
                                <div class="pear-card2">
                                    <div class="title">空闲内存</div>
                                    <div class="count pear-text" id="memory_free">-</div>
                                </div>
                            </div>
                            <div class="layui-col-md6 layui-col-sm6 layui-col-xs6">
                                <div class="pear-card2">
                                    <div class="title">最大内存</div>
                                    <div class="count pear-text" id="memory_total">-</div>
                                </div>
                            </div>
                            <div class="layui-col-md6 layui-col-sm6 layui-col-xs6">
                                <div class="pear-card2">
                                    <div class="title">已用内存</div>
                                    <div class="count pear-text" id="memory_used">-</div>
                                </div>
                            </div>
                            <div class="layui-col-md6 layui-col-sm6 layui-col-xs6">
                                <div class="pear-card2">
                                    <div class="title">内存使用</div>
                                    <div class="count pear-text" id="memory_usage">-%</div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="layui-col-md12">
                <div class="layui-card">
                    <div class="layui-card-header">主机监控</div>
                    <div class="layui-card-body">
                        <div class="layui-tab custom-tab layui-tab-brief" lay-filter="docDemoTabBrief">
                            <div id="echarts-records" style="background-color:#ffffff;min-height:400px;"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="layui-col-md4">
        <div class="layui-card">
            <div class="layui-card-header">主机信息</div>
            <div class="layui-card-body">
                <table class="layui-table">
                    <thead>
                    <tr>
                        <th>属性</th>
                        <th>值</th>
                    </tr>
                    </thead>
                    <tbody>
                    <tr>
                        <td>名称</td>
                        <td id="hostname">{{ hostname }}</td>
                    </tr>

                    <tr>
                        <td>系统</td>
                        <td id="system_version">{{ system_version }}</td>
                    </tr>
                    <tr>
                        <td>开机时间</td>
                        <td id="boot_time">{{ boot_time }}</td>
                    </tr>
                    <tr>
                        <td>运行时长</td>
                        <td id="up_time_format">{{ up_time_format }}</td>
                    </tr>
                    <tr>
                        <td>Python 版本</td>
                        <td id="python_version">{{ python_version }}</td>
                    </tr>
                    <tr>
                        <td>程序操作</td>
                        <td>
                            <a href="javascript:kill();"
                               class="layui-btn layui-btn-xs layui-btn-primary">关闭程序</a>
                        </td>
                    </tr>
                    </tbody>
                </table>
            </div>
        </div>
        <div class="layui-card">
            <div class="layui-card-header">磁盘信息</div>
            <div class="layui-card-body" id="disk-info-card">
                加载中......
            </div>
        </div>
    </div>
</div>

<div id="tooltip" style="background-color: unset !important;">
    <div class="layui-card" style="box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);">
        <div class="layui-card-body" style="text-align: center" id="tooltip-cpus">
            加载中......
        </div>
    </div>
</div>


{% include 'system/common/footer.html' %}
<script>
    var systemInfo = null;  // 存储获取到的系统信息对象

    function memoryFormat(memory) {
        if (memory >= 1024 ** 4 * 2) {
            return (memory / 1024 ** 4).toFixed(2) + 'TB';
        } else if (memory >= 1024 ** 3 * 2) {
            return (memory / 1024 ** 3).toFixed(2) + 'GB';
        } else if (memory >= 1024 ** 2 * 2) {
            return (memory / 1024 ** 2).toFixed(2) + 'MB';
        } else if (memory >= 1024 ** 1 * 2) {
            return (memory / 1024 ** 1).toFixed(2) + 'KB';
        } else {
            return memory + 'B';
        }
    }

    function diskinfo(index) {
        data = systemInfo.disk_partitions_list[index];

        layui.laytpl(`
                <ul>
                    <li>分区类型: <%= d.fstype %></li>
                    <li>磁盘大小: <%= memoryFormat(d.total) %></li>
                    <li>空闲大小: <%= memoryFormat(d.free) %></li>
                    <li>已经使用: <%= memoryFormat(d.used) %> (<%= d.percent %>%)</li>
                </ul>
            `, {
            open: '<%',
            close: '%>'
        }).render(data, function (string) {
            layui.layer.alert(string);
        });
    }

    function kill() {
        var success = true;
        layui.$.ajax({
            url: "/system/monitor/kill",
            success: function (res) {
                layui.popup.failure(res.msg);
                success = false;
            },
            complete: function (xhr) {
                if (success) layui.popup.success("已发送关闭命令。");
            }
        });
    }

    layui.use(['layer', 'echarts', 'popup'], function () {
        var $ = layui.jquery,
            echarts = layui.echarts;
        let popup = layui.popup;
        let laytpl = layui.laytpl;

        var echartsRecords = echarts.init(document.getElementById('echarts-records'), 'walden');


        $('#host-info-card').hover(
            function () {
                $('#tooltip').addClass('show');

                // 获取 #cpus_percent-card 的位置、尺寸和宽度
                const card = $(this);
                const cardOffset = card.offset(); // 元素相对于文档的偏移量
                const cardHeight = card.outerHeight(); // 元素的高度
                const cardWidth = card.outerWidth(); // 元素的宽度

                // 设置悬浮提示框的宽度和位置
                $('#tooltip').css({
                    top: cardOffset.top + cardHeight + 2, // 放在元素下方 5px
                    left: cardOffset.left - 5, // 与元素左对齐
                    width: cardWidth - 10, // 宽度与元素一致
                });
            },
            function () {
                $('#tooltip').removeClass('show');
            }
        );

        $("body").on("click", "[data-url]", function () {
            parent.layui.tab.addTabOnlyByElem("content", {
                id: $(this).attr("data-id"),
                title: $(this).attr("data-title"),
                url: $(this).attr("data-url"),
                close: true
            })
        })


        let color = [
            "#0090FF",
            "#36CE9E",
            "#FFC005",
            "#FF515A",
            "#8B5CFF",
            "#00CA69"
        ];

        const hexToRgba = (hex, opacity) => {
            let rgbaColor = "";
            let reg = /^#[\da-f]{6}$/i;
            if (reg.test(hex)) {
                rgbaColor =
                    `rgba(${parseInt("0x" + hex.slice(1, 3))},${parseInt(
                        "0x" + hex.slice(3, 5)
                    )},${parseInt("0x" + hex.slice(5, 7))},${opacity})`;
            }
            return rgbaColor;
        }

        let echartData = [];

        var option = {
            backgroundColor: 'transparent',
            color: color,
            legend: {
                right: 10,
                top: 10
            },
            tooltip: {
                trigger: "axis",
                axisPointer: {
                    type: 'shadow',
                    shadowStyle: {
                        shadowColor: 'rgba(225,225,225,1)',
                        shadowBlur: 5
                    }
                }
            },
            grid: {
                backgroundColor: 'transparent',
                top: 100,
                containLabel: true
            },
            xAxis: [{
                type: "category",
                boundaryGap: false,
                axisLabel: {
                    formatter: '{value}',
                    textStyle: {
                        color: "#333"
                    }
                },
                axisLine: {
                    lineStyle: {
                        color: "#D9D9D9"
                    }
                },
                data: null
            }],
            yAxis: [{
                type: "value",
                name: '单位：百分比',
                axisLabel: {
                    textStyle: {
                        color: "#666"
                    }
                },
                nameTextStyle: {
                    color: "#666",
                    fontSize: 12,
                    lineHeight: 40
                },
                splitLine: {
                    lineStyle: {
                        type: "dashed",
                        color: "#E9E9E9"
                    }
                },
                axisLine: {
                    show: false
                },
                axisTick: {
                    show: false
                }
            }],
            series: [{
                name: "CPU",
                type: "line",
                smooth: true,
                symbolSize: 8,
                zlevel: 3,
                lineStyle: {
                    normal: {
                        color: color[0],
                        shadowBlur: 3,
                        shadowColor: hexToRgba(color[0], 0.5),
                        shadowOffsetY: 8
                    }
                },
                areaStyle: {
                    normal: {
                        color: new echarts.graphic.LinearGradient(
                            0,
                            0,
                            0,
                            1,
                            [{
                                offset: 0,
                                color: hexToRgba(color[0], 0.3)
                            },
                                {
                                    offset: 1,
                                    color: hexToRgba(color[0], 0.1)
                                }
                            ],
                            false
                        ),
                        shadowColor: hexToRgba(color[0], 0.1),
                        shadowBlur: 10
                    }
                },
                data: null
            }, {
                name: '内存',
                type: "line",
                smooth: true,
                symbolSize: 8,
                zlevel: 3,
                lineStyle: {
                    normal: {
                        color: color[1],
                        shadowBlur: 3,
                        shadowColor: hexToRgba(color[1], 0.5),
                        shadowOffsetY: 8
                    }
                },
                areaStyle: {
                    normal: {
                        color: new echarts.graphic.LinearGradient(
                            0,
                            0,
                            0,
                            1,
                            [{
                                offset: 0,
                                color: hexToRgba(color[1], 0.3)
                            },
                                {
                                    offset: 1,
                                    color: hexToRgba(color[1], 0.1)
                                }
                            ],
                            false
                        ),
                        shadowColor: hexToRgba(color[1], 0.1),
                        shadowBlur: 10
                    }
                },
                data: null
            }]
        };

        echartsRecords.setOption(option);

        window.onresize = function () {
            echartsRecords.resize();
        };

        ajaxPolling();
        setInterval(ajaxPolling, 1000 * 5);

        function ajaxPolling() {
            $.ajax({
                url: "/system/monitor/polling",
                success: function (result) {
                    data = result.data;
                    systemInfo = data;


                    // 更新使用率等信息
                    document.querySelector("#cpu_count").innerText = data.cpu_count;
                    document.querySelector("#cpus_percent").innerText = data.cpus_percent + "%";
                    document.querySelector("#cpu_idle_percent").innerText = data.cpu_idle_percent + "%";
                    document.querySelector("#cpu_wait_percent").innerText = data.cpu_wait_percent + "%";

                    document.querySelector("#memory_used").innerText = memoryFormat(data.memory_used);
                    document.querySelector("#memory_total").innerText = memoryFormat(data.memory_total);
                    document.querySelector("#memory_free").innerText = memoryFormat(data.memory_free);
                    document.querySelector("#memory_usage").innerText = data.memory_usage + "%";

                    // 基本信息
                    document.querySelector("#hostname").innerText = data.basic_info.hostname;
                    document.querySelector("#system_version").innerText = data.basic_info.system_version;
                    document.querySelector("#boot_time").innerText = data.basic_info.boot_time;
                    document.querySelector("#up_time_format").innerText = data.basic_info.up_time_format;
                    document.querySelector("#python_version").innerText = data.basic_info.python_version;


                    // 更新每一个CPU使用率
                    laytpl(`
                      <ul>
                        <%# layui.each(d, function(index, data){ %>
                        <li>
                            <span class="layui-badge layui-bg-blue">CPU <%= data[0] %>: <%= data[1] %>%</span>
                        </li>
                        <%#  }); %>
                    </ul>
                    `, {
                        open: '<%',
                        close: '%>'
                    }).render(data.cpu_percent_per_core, function (string) {
                        document.querySelector("#tooltip-cpus").innerHTML = string;
                    });


                    // 更新硬盘信息
                    laytpl(`
                    <fieldset class="layui-elem-field layui-field-title"></fieldset>
                    <%# layui.each(d, function(index, data){ %>
                    <div class="layui-row" style="display: flex; align-items: center;">
                        <div class="progress-ring" style="margin-right: 50px;">
                            <svg class="circle" width="120" height="120" viewBox="0 0 120 120">
                                <circle class="circle-bg" cx="60" cy="60" r="54"/>
                                <circle class="circle-progress" cx="60" cy="60" r="54" style="--progress: <%= data.percent %>"/>
                            </svg>
                            <div class="progress-text"><%= data.device %></div>
                        </div>
                        <div class="layui-col-space10" style="display: flex; align-items: center;">
                            <ul>
                                <li>分区类型: <%= data.fstype %></li>
                                <li>磁盘大小: <%= memoryFormat(data.total) %></li>
                                <li>空闲大小: <%= memoryFormat(data.free) %></li>
                                <li>已经使用: <%= memoryFormat(data.used) %> (<%= data.percent %>%)</li>
                                <li>
                                    <a href="javascript:diskinfo(<%= index %>)" data-id="1"
                                       class="layui-btn layui-btn-xs layui-btn-primary pear-reply">查看详情
                                    </a>
                                </li>
                            </ul>
                        </div>
                    </div>
                    <fieldset class="layui-elem-field layui-field-title"></fieldset>
                    <%# }) %>
                    `, {
                        open: '<%',
                        close: '%>'
                    }).render(data.disk_partitions_list, function (string) {
                        document.querySelector("#disk-info-card").innerHTML = string;
                    });


                    // 更新图表
                    echartData.push({
                        name: data.time_now,
                        cpu_percent: data.cpus_percent,
                        memory_percent: data.memory_usage
                    });

                    if (echartData.length > 8) {
                        echartData.shift();
                    }

                    xAxisData = echartData.map(v => v.name);
                    yAxisData1 = echartData.map(v => v.cpu_percent);
                    yAxisData2 = echartData.map(v => v.memory_percent);

                    option.xAxis[0].data = xAxisData;
                    option.series[0].data = yAxisData1;
                    option.series[1].data = yAxisData2;

                    echartsRecords.setOption(option);

                },
                error: function (xhr, type, errorThrown) {
                }
            })

        }


    });
</script>
</body>
</html>